// 使用信号量，控制多任务对全局变量的读写

#include <Arduino.h>

#define CODE 0


#if 0 == CODE

    volatile uint32_t inve = 100;
    volatile uint32_t reta = 0;
    volatile uint32_t onli = 0;
    
    //mutex把手
    SemaphoreHandle_t mutex_h = NULL;
    
    TickType_t time_out = 1000;
    
    
    void retail_task(void *p){
        while(1){
            //检测是否获得钥匙，信号量即钥匙
            if(xSemaphoreTake(mutex_h, time_out) == pdPASS){
                
                
                //获取钥匙后称为 临界区，此处越短越好
                uint32_t temp = inve;
                
                //随机延时
                for(int i; i < random(10, 100); i++){
                    vTaskDelay(pdMS_TO_TICKS(i));
                }
                
                if(inve > 0){
                    inve = temp - 1;
                    reta++;
                    
                    //释放钥匙
                    xSemaphoreGive(mutex_h);
                    
                    
                    
                    
                }else{
                    //无法获取钥匙的处理方式，此处不需要
                }
            }
            
            vTaskDelay(100);
        }
    }
    
    
    
    void online_task(void *p){
        while(1){
        
        
            //检测是否获得钥匙，信号量即钥匙
            //不要在任务开始就获取钥匙，那样占据资源
            //应该在需要时，才获取钥匙，并尽快释放钥匙
            if(xSemaphoreTake(mutex_h, time_out) == pdPASS){
                
                
                //获取钥匙后称为 临界区，此处越短越好
                uint32_t temp = inve;
                
                //随机延时
                for(int i; i < random(10, 100); i++){
                    vTaskDelay(pdMS_TO_TICKS(i));
                }
                
                if(inve > 0){
                    inve = temp - 1;
                    onli++;
                    
                    //释放钥匙
                    xSemaphoreGive(mutex_h);
                    
                    
                    
                    
                }else{
                    //无法获取钥匙的处理方式，此处不需要
                }
            }
            
            vTaskDelay(100);
        }
    }
    
    
    
    void show_task(void *p){
        while(1){
            Serial.printf("库存数量：%d\n销售数量：%d\n线上销售数量：%d\n", inve, reta, onli);
            
            if(inve == 0){
                Serial.printf("\n----销售概况----\n  总销售数量：%d\n  超售数量：%d\n", reta + onli, inve - (reta + onli));
            }
            vTaskDelay(pdMS_TO_TICKS(100));
        }
    }
    
    
    
    
    void setup() {
        Serial.begin(115200);
        
        mutex_h = xSemaphoreCreateMutex();
        
        if(mutex_h == NULL){
            Serial.printf("内存不足，无法创建信号量");
            
        }else{
            xTaskCreate(online_task, "", 1024*4, NULL, 1, NULL);
            xTaskCreate(retail_task, "", 1024*4, NULL, 1, NULL);
            xTaskCreate(show_task, "", 1024*4, NULL, 1, NULL);
        }
    }

    void loop() {
        
    }

#endif